import {Row, Col, Layout, Tree, Space,Spin} from 'antd';

import React, { Component } from 'react';

import LayoutContentWrapper from '@iso/components/utility/layoutWrapper';
import LayoutContent from '@iso/components/utility/layoutContent';
import PageHeader from '@iso/components/utility/pageHeader';
import TableWrapper from "@iso/containers/Tables/AntTables/AntTables.styles";

import {
    DateCell,
    ImageCell,
    LinkCell,
    TextCell,
} from '@iso/components/Tables/HelperCells';

import {

    FolderOutlined,
    FileImageOutlined,
    FileWordOutlined,
    FileExcelOutlined,
    FilePptOutlined,
    FilePdfOutlined,
    FileUnknownOutlined,
    FileZipOutlined,
    UploadOutlined,
    FolderAddOutlined,
    HomeOutlined,
    EditOutlined, FolderOpenOutlined

} from '@ant-design/icons';

import Button from '@iso/components/uielements/button';
import axios from "../../../../http";
import Qs from 'qs'
import {showErrorMessage, showSuccessMessage} from "@iso/containers/Feedback/Message/MessageUtils";
import {Fieldset, Form, Label} from "@iso/containers/FirestoreCRUD/Article/Article.styles";
import Input from '@iso/components/uielements/input';

import Popconfirm from '@iso/containers/Feedback/Popconfirm/PopconfirmUtils';
import Modals from '@iso/components/Feedback/Modal';
import ModalStyle from '@iso/containers/Feedback/Modal/Modal.styles';
import WithDirection from '@iso/lib/helpers/rtl';

import FileUploadButton from "./FileUploadButton";
import FileLink from "./FileLink";

const isoModal = ModalStyle(Modals);
const Modal = WithDirection(isoModal);

const { Header, Content,Sider } = Layout;


export default  class FileManager extends React.Component {
    state = {
        spinning:false,
        fileList: [],
        selectedRowKeys:[],
        currentDirectory:'',
        modalEditVisible:false,
        modalVisible:false,
        directoryName:'',
        newFileName:'',
        treeData:[]
    };


    renderCell = (object, type, key) => {
        const value = object[key];
        switch (type) {
            case 'ImageCell':
                return ImageCell(value);
            case 'DateCell':
                return DateCell(value);
            case 'LinkCell':
                return LinkCell(value);
            default:
                return TextCell(value);
        }
    };
     isAssetTypeAnImage=(ext)=> {
        return ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff'].
        indexOf(ext.toLowerCase()) !== -1;
    }

    getFileNameSuffix=(fileName)=>{

        let index= fileName.lastIndexOf(".");

        let ext = fileName.substr(index+1);

        return ext;
    }


    renderNameCell = (object, key) => {
        let name = object[key];
        const isDirectory=object['isDirectory'];
        if(isDirectory==true){
           return [<FolderOutlined/>,name];
        }
        let fileNameSuffix=this.getFileNameSuffix(name);
        if(this.isAssetTypeAnImage(fileNameSuffix)){
            return [<FileImageOutlined/>,<FileLink file={object} />];
        }
        switch (fileNameSuffix) {
            case 'doc':
                return [<FileWordOutlined/>,<FileLink file={object} />];
            case 'docx':
                return [<FileWordOutlined/>,<FileLink file={object} />];
            case 'xls':
                return [<FileExcelOutlined/>,<FileLink file={object} />];
            case 'xlsx':
                return [<FileExcelOutlined/>,<FileLink file={object} />];
            case 'ppt':
                return [<FilePptOutlined/>,<FileLink file={object} />];
            case 'pptx':
                return [<FilePptOutlined/>,<FileLink file={object} />];
            case 'pdf':
                return [<FilePdfOutlined/>,<FileLink file={object} />];
            case 'zip':
                return [<FileZipOutlined/>,<FileLink file={object} />];
            default:
                return [<FileUnknownOutlined/>,<FileLink file={object} />];
        }

    };

    getColumns(){
        const columns = [ {
            title: '名称 ',
            key: 'name',
            width: 100,
            render: object => this.renderNameCell(object,  'name'),

        },{
            title: '大小',
            key: 'size',
            width: 100,
            render: object =>  this.renderCell(object, 'TextCell', 'size'),
        },{
            title: '类型',
            key: 'type',
            width: 100,
            render: object =>  this.renderCell(object, 'TextCell', 'type'),
        },{
            title: '最后修改时间',
            key: 'lastModified',
            width: 100,
            render: object => this.renderCell(object, 'TextCell', 'lastModified'),
        }];

        const sortColumns = [
            { ...columns[0], sorter: false },
            { ...columns[1], sorter: false },

            { ...columns[3], sorter: false }
        ];
        return sortColumns;
    }

    onSelectedUpdate=(fileList,currentDirectory)=>{
        this.setState({fileList:fileList})
        this.setState({currentDirectory:currentDirectory})
    }

    onSelectChange = selectedRowKeys => {
        this.setState({ selectedRowKeys:selectedRowKeys });
    };

    deleteFile=()=>{
        let entity={'filePaths':this.state.selectedRowKeys};
        axios.post('api/objectStore/file/delete', Qs.stringify({
            requestJson:JSON.stringify(entity)
        }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
            .then((response)=>{
                let  data=response.data;
                if(data.status==1){
                    this.fileTreeOnLoadData({key:this.state.currentDirectory});
                    showSuccessMessage(data.message);
                }else{
                    showErrorMessage(data.message);
                }
            })
            .catch(function (error) {
                showErrorMessage(error);
            });
    }

    createDirectory=()=>{
        let directoryPath="";
        if(this.state.currentDirectory==""){
            directoryPath=this.state.directoryName;
        }else{
            directoryPath=this.state.currentDirectory+"/"+this.state.directoryName;
        }
        axios.post('api/objectStore/file/directory/create', Qs.stringify({
            directoryPath:directoryPath
        }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
            .then((response)=>{
                let  data=response.data;
                if(data.status==1){
                    this.setState({modalVisible:false})
                    this.fileTreeOnLoadData({key:this.state.currentDirectory});
                    showSuccessMessage(data.message);
                }else{
                    showErrorMessage(data.message);
                }
            })
            .catch(function (error) {
                showErrorMessage(error);
            });
    }

    rename=()=>{
        axios.post('api/objectStore/file/rename', Qs.stringify({
            oldFilePath:this.state.selectedRowKeys[0],
            newFilePath:this.state.newFileName
        }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
            .then((response)=>{
                let  data=response.data;
                if(data.status==1){
                    this.setState({modalEditVisible:false})
                    this.fileTreeOnLoadData({key:this.state.currentDirectory});
                    showSuccessMessage(data.message);
                }else{
                    showErrorMessage(data.message);
                }
            })
            .catch(function (error) {
                showErrorMessage(error);
            });
    }

    onRecordChange = (event, key) => {
        let state={};
        state[key]=event.target.value;
        this.setState(state)
    };

     updateTreeData=(list, key, children)=> {
        return list.map((node) => {
            if (node.key === key) {
                return { ...node, children };
            }
            if (node.children) {
                return { ...node, children: this.updateTreeData(node.children, key, children) };
            }
            return node;
        });
    }

    fileTreeOnLoadData = (node) =>
        new Promise((resolve) => {
            if (node.children) {
                resolve();
                return;
            }
            let key=node.key;
            axios.post('api/objectStore/file/list', Qs.stringify({
                currentDirectory:key
            }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
                .then((response)=>{
                    let  data=response.data;
                    if(data.status==1){
                        let updatedChildren=this.convertToTreeData(data);
                        this.onSelectedUpdate(data.data,key);
                        if(key===""){
                           this.setState({"treeData":updatedChildren});
                        }else{
                            let updatedTreeData=this.updateTreeData(this.state.treeData, key, updatedChildren)
                            this.setState({"treeData":updatedTreeData});
                        }
                        resolve();
                    }else{
                        showErrorMessage(data.message);
                    }
                })
                .catch(function (error) {
                    showErrorMessage(error);
                });
        });

     convertToTreeData=(data)=>{
        let itemList=data.data;
        let treeData=[];
        for(let i=0;i<itemList.length;i++){
            let item=itemList[i];
            if(item.isDirectory==true){
                let treeNodeData= {
                    icon:({ selected }) => (selected ? <FolderOpenOutlined /> : <FolderOutlined />) ,
                    title: item.name,
                    key: item.key
                }
                treeData.push(treeNodeData);
            }
        }
        return treeData;
    }

     fileTreeOnSelect = (selectedKeys, info) => {
        new Promise((resolve) => {
            let key=info.node.key;
            axios.post('api/objectStore/file/list', Qs.stringify({
                currentDirectory:key
            }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
                .then((response)=>{
                    let  data=response.data;
                    if(data.status==1){
                        this.setState({selectedRowKeys:[]})
                        this.onSelectedUpdate(data.data,key);
                        resolve();
                    }else{
                        showErrorMessage(data.message);
                    }
                })
                .catch(function (error) {
                    showErrorMessage(error);
                });
        });

    }

    goHome = () => {
        new Promise((resolve) => {
            let key=""
            axios.post('api/objectStore/file/list', Qs.stringify({
                currentDirectory:key
            }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
                .then((response)=>{
                    let  data=response.data;
                    if(data.status==1){
                        this.setState({selectedRowKeys:[]})
                        this.onSelectedUpdate(data.data,key);
                        resolve();
                    }else{
                        showErrorMessage(data.message);
                    }
                })
                .catch(function (error) {
                    showErrorMessage(error);
                });
        });

    }

    upload=(fileContentList)=>{
        let entity={fileContentList:fileContentList,
            currentDirectory:this.state.currentDirectory+'/'
        }
        this.setState({spinning:true});
        axios.post('api/objectStore/file/upload', Qs.stringify({
            requestJson:JSON.stringify(entity)
        }),{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
            .then((response)=>{
                this.setState({spinning:false});
                let  data=response.data;
                if(data.status==1){
                    this.fileTreeOnLoadData({key:this.state.currentDirectory});
                }else{
                    showErrorMessage(data.message);
                }
            })
            .catch(function (error) {
                showErrorMessage(error);
                this.setState({spinning:false});
            });
    }

    componentDidMount() {
       this.fileTreeOnLoadData({key:""});
    }



    render() {
        const { selectedRowKeys } = this.state;
        const rowSelection = {
            selectedRowKeys,
            onChange: this.onSelectChange,
        };
        return (
            <Spin spinning={this.state.spinning} >
            <LayoutContentWrapper >
                <PageHeader>
                    文件管理
                </PageHeader>

                <LayoutContent>
                    <Modal
                        visible={this.state.modalVisible}
                        title="新建文件夹"
                        onCancel={()=>{this.setState({modalVisible:false})}}
                        footer={[
                            <Button key="back" size="small" onClick={()=>{this.setState({modalVisible:false})}}>
                                取消
                            </Button>,
                            <Button
                                key="submit"
                                type="primary"
                                size="small"
                                onClick={this.createDirectory}
                            >
                                确定
                            </Button>,
                        ]}
                    >
                        <Form>
                            <Fieldset>
                                <Label>名称:</Label>
                                <Input
                                    label="名称"
                                    placeholder="名称"
                                    value={this.state.directoryName}
                                    onChange={e => this.onRecordChange(e, 'directoryName')}
                                />
                            </Fieldset>

                        </Form>

                    </Modal>


                    <Modal
                        visible={this.state.modalEditVisible}
                        title="重命名"
                        onCancel={()=>{this.setState({modalEditVisible:false})}}
                        footer={[
                            <Button key="back" size="small" onClick={()=>{this.setState({modalEditVisible:false})}}>
                                取消
                            </Button>,
                            <Button
                                key="submit"
                                type="primary"
                                size="small"
                                onClick={this.rename}
                            >
                                确定
                            </Button>,
                        ]}
                    >
                        <Form >
                            <Fieldset>
                                <Label>名称:</Label>
                                <Input
                                    label="名称"
                                    placeholder="名称"
                                    value={this.state.newFileName}
                                    onChange={e => this.onRecordChange(e, 'newFileName')}
                                />
                            </Fieldset>

                        </Form>

                    </Modal>

                    <Layout >
                        <Sider   style={{ background:'rgba(255, 255, 255, 0.3)' ,overflow:'auto'  }}>
                            <div className="logo" />
                            <Tree showIcon loadData={this.fileTreeOnLoadData}   onSelect={this.fileTreeOnSelect} treeData={this.state.treeData} />
                        </Sider>
                        <Layout >
                            <Header  style={{ padding: 0 }} style={{ background:'rgba(255, 255, 255, 0.3)' }} >
                                <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
                                    <Col className="gutter-row" span={4}>

                                        <Button
                                            key="submit"
                                            type="primary"
                                            size="small"
                                            icon={<HomeOutlined/>}
                                            onClick={
                                                ()=>{
                                                    this.goHome();
                                                }
                                            }
                                        >
                                            主目录
                                        </Button>

                                    </Col>
                                    <Col className="gutter-row" span={3}>

                                        <FileUploadButton config={{
                                            id:'upload-button-1',
                                            accept: [".png", ".jpg",".zip",".pdf",".mp3",".mp4"],
                                        }} onChange={this.upload}/>

                                    </Col>
                                    <Col className="gutter-row" span={4}>

                                        <Button
                                            key="submit"
                                            type="primary"
                                            size="small"
                                            icon={<FolderAddOutlined/>}
                                            onClick={()=>{this.setState({modalVisible:true,directoryName:''})}}
                                        >
                                            新建文件夹
                                        </Button>

                                    </Col>
                                    <Col className="gutter-row" span={3}>

                                        <Button
                                            key="submit"
                                            type="primary"
                                            size="small"
                                            icon={<EditOutlined/>}
                                            disabled={this.state.selectedRowKeys.length!=1}
                                            onClick={()=>{this.setState({
                                                modalEditVisible:true,
                                                newFileName:this.state.selectedRowKeys[0]
                                            })}}
                                        >
                                            重命名
                                        </Button>

                                    </Col>
                                    <Col className="gutter-row" span={3}>

                                        <Popconfirm
                                            title="确定要执行删除操作吗？"
                                            okText="是"
                                            cancelText="否"
                                            onConfirm={this.deleteFile}
                                        >

                                            <Button
                                                key="submit"
                                                type="danger"
                                                size="small"
                                                disabled={this.state.selectedRowKeys.length==0}
                                            >
                                                删除
                                            </Button>

                                        </Popconfirm>

                                    </Col>
                                </Row>

                            </Header>
                            <Content style={{ margin: '0 16px' }}>

                                <div className="site-layout-background" style={{ padding: 24 }}>

                                    <TableWrapper
                                        columns={this.getColumns()}
                                        dataSource={this.state.fileList}
                                        className="isoSortingTable"
                                        pagination={false}
                                        rowSelection={rowSelection}

                                    />

                                </div>

                            </Content>

                        </Layout>
                    </Layout>
                </LayoutContent>

            </LayoutContentWrapper>
            </Spin>

        );
    }
}